package com.duobaoyu.dby.supply.message.listener.hander.admin;

import cn.hutool.core.codec.Base64;
import com.alibaba.fastjson.JSON;
import com.duobaoyu.dby.channel.adapter.enums.OperationTypeEnum;
import com.duobaoyu.dby.common.core.constant.StringPool;
import com.duobaoyu.dby.common.mybatis.util.EnumUtils;
import com.duobaoyu.dby.supply.biz.enums.LockKeys;
import com.duobaoyu.dby.supply.biz.enums.RedisKeys;
import com.duobaoyu.dby.supply.biz.producer.constant.SupplyChainMQConstants;
import com.duobaoyu.dby.supply.core.cache.service.RedissonService;
import com.duobaoyu.dby.supply.core.common.util.DeflaterUtils;
import com.duobaoyu.dby.supply.core.dinger.annotation.DingerTalk;
import com.duobaoyu.dby.supply.core.rocketmq.handler.AbstractClusterMessageHandler;
import com.duobaoyu.dby.supply.db.entity.message.SystemLog;
import com.duobaoyu.dby.supply.db.repository.message.SystemLogRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.rocketmq.common.message.MessageExt;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Component;

/**
 * @author liyang
 * @version 1.0.0
 * @ClassName SupplyChainSystemLogMessageHandler
 * @Description 供应链日志消息
 * @createTime 09:49:00 2022/06/09
 */
@Slf4j
@Component
@RefreshScope
@RequiredArgsConstructor
public class SupplyChainSystemLogMessageHandler extends AbstractClusterMessageHandler<SystemLog> {

	@Value("${dby.supply.chain.log.select:false}")
	private Boolean selectLogSave;
	private final RedissonService redissonService;
	private final SystemLogRepository systemLogRepository;

	@Override
	public String getTopic() {
		return SupplyChainMQConstants.SupplyChainTopic.SUPPLY_CHAIN_ADMIN_TOPIC;
	}

	@Override
	public String getTag() {
		return SupplyChainMQConstants.SupplyChainTopic.SupplyChainAdminTag.SYSTEM_LOG_TAG;
	}

	@Override
	@DingerTalk(title = "接收到供应链日志消息Consumer")
	public boolean messageHandler(SystemLog systemLog, MessageExt messageExt) {
		if(log.isDebugEnabled()) {
			log.debug("接收到供应链日志消息:systemLog = {}",systemLog);
		}
		try {
			boolean result = false;
			if(EnumUtils.eq(OperationTypeEnum.SELECT,systemLog.getOperationType()) && this.selectLogSave) {
				return true;
			}
			if(StringUtils.isNotBlank(systemLog.getId())) {
				systemLog.setId(null);
			}
			if(StringUtils.isNotBlank(systemLog.getParams()) && !Base64.isBase64(systemLog.getParams())) {
				systemLog.setParams(DeflaterUtils.zipString(systemLog.getParams()));
			}
			if(StringUtils.isNotBlank(systemLog.getResponse()) && !Base64.isBase64(systemLog.getResponse())) {
				systemLog.setResponse(DeflaterUtils.zipString(systemLog.getResponse()));
			}
			if(StringUtils.isBlank(systemLog.getParams())) {
				systemLog.setParams(StringPool.EMPTY);
			}
			if(StringUtils.isBlank(systemLog.getResponse())) {
				systemLog.setResponse(StringPool.EMPTY);
			}
			if(StringUtils.isBlank(systemLog.getException())) {
				systemLog.setException(StringPool.EMPTY);
			}
			if(StringUtils.isBlank(systemLog.getUniqueKey())) {
				systemLog.setUniqueKey(DigestUtils.md5Hex(JSON.toJSONString(systemLog)));
			}
			boolean exists = systemLogRepository.existsByUniqueKey(systemLog.getUniqueKey());
			if(!exists) {
				result = redissonService.tryLock(RedisKeys.LOCK_REDIS.formatKey(LockKeys.SYSTEM_LOG_MESSAGE.formatKey(systemLog.getUniqueKey())),() -> true,() -> {
					boolean lockExists = systemLogRepository.existsByUniqueKey(systemLog.getUniqueKey());
					return lockExists ? lockExists : systemLogRepository.save(systemLog);
				});
			}
			if(log.isDebugEnabled()) {
				log.debug("接收到供应链日志消息处理完成:systemLog = {},result={}",systemLog,result);
			}
			return result;
		}catch (DuplicateKeyException e) {
			log.warn("重复供应链日志消息:systemLog = {}",systemLog);
			return true;
		}
	}
}
